Skip to content

feat(init): add init command for guided Sentry project setup#283

Open
betegon wants to merge 77 commits intomainfrom
feat/init-command
Open

feat(init): add init command for guided Sentry project setup#283
betegon wants to merge 77 commits intomainfrom
feat/init-command

Conversation

@betegon
Copy link
Member

@betegon betegon commented Feb 23, 2026

Summary

Adds sentry init — an AI-powered wizard that walks users through adding Sentry to their project. It detects the platform, installs the SDK, instruments the code, and configures error monitoring, tracing, and session replay.

Changes

Core wizard

  • New init command backed by a Mastra AI workflow (hosted at getsentry/cli-init-api) that handles platform detection, SDK installation, and code instrumentation
  • ASCII banner, AI transparency note, and review reminder in the wizard UX
  • Tracing: unique trace IDs per wizard run with flattened span hierarchy
  • Python platforms use venv for isolated dependency installation
  • Magic values extracted into named constants (constants.ts)
  • Docs page added to cli.sentry.dev

Security hardening

  • Shell metacharacter blocklist: () subshell bypass, > < & redirection/background, $ ' " \ expansion/escaping, { } * ? glob/brace expansion, # shell comment
  • Environment variable injection blocking (VAR=value cmd pattern)
  • Remote-supplied cwd validation against project directory
  • Dangerous executable blocklist and path-traversal prevention
  • File descriptor cleanup on readSync failure
  • Cross-platform shell execution ({ shell: true } instead of hardcoded sh)

Performance

Testing & CI

  • Wizard-runner unit tests (coverage 5.94% → 99.42%)
  • Banner extracted to src/lib/banner.ts to break circular import
  • Mock isolation fixes (spyOn instead of mock.module where possible)
  • Simplified coverage pipeline (removed merge-lcov workaround)

Eval suite

The eval suite validates that the wizard produces correct, buildable Sentry instrumentation for each supported platform. It uses a 3-phase test architecture:

Phase 1: Wizard run

Each test scaffolds a fresh project from a platform template, then runs the full sentry init wizard against it. The wizard output (exit code, stdout/stderr, git diff, new files) is captured for the next phases.

Phase 2: Hard assertions (deterministic)

Five code-based pass/fail checks that run without any LLM:

  1. exit-code — wizard exits 0
  2. sdk-installed — the Sentry SDK package appears in the dependency file (package.json / requirements.txt)
  3. init-presentSentry.init (or sentry_sdk.init) appears in changed or new files
  4. no-placeholder-dsn — no leftover placeholder DSNs (___PUBLIC_DSN___, YOUR_DSN_HERE, etc.)
  5. build-succeedsnpm run build / equivalent passes after the wizard's changes

Phase 3: LLM judge (per-feature)

For each feature (errors, tracing, replay, logs, profiling, etc.), an LLM judge scores correctness:

  • Official Sentry docs are fetched as ground truth (URLs mapped in feature-docs.json)
  • GPT-4o evaluates the wizard's diff + new files against the docs on 4 criteria: feature-initialized, correct-imports, no-syntax-errors, follows-docs
  • Each criterion is scored pass/fail/unknown; the overall feature score must be >= 0.5

Platforms

6 platform templates are covered:

Platform Template SDK
Express express/ @sentry/node
Next.js nextjs/ @sentry/nextjs
SvelteKit sveltekit/ @sentry/sveltekit
React + Vite react-vite/ @sentry/react
Flask python-flask/ sentry-sdk
FastAPI python-fastapi/ sentry-sdk

Running

bun run test:init-eval          # all platforms

Requires SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT, and optionally OPENAI_API_KEY (LLM judge is skipped without it).

Test Plan

  • All init unit tests pass (124 tests across 7 files)
  • bun run lint and bun run typecheck pass
  • CI passes (unit tests, e2e, lint, typecheck, build)
  • CI workflow for eval is tracked separately in Run init evals on CI #290

🤖 Generated with Claude Code

betegon and others added 21 commits February 17, 2026 20:48
Adds `sentry init` wizard that walks users through project setup via
the Mastra API, handling DSN configuration, SDK installation prompts,
and local file operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sends tags and metadata (CLI version, OS, arch, node version) with
startAsync and resumeAsync calls so workflow runs are visible and
filterable in Mastra Studio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Import randomBytes and generate a hex trace ID so all
suspend/resume calls within a single wizard run share one trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a synthetic parentSpanId to tracingOptions so all workflow run
spans become siblings under the same parent instead of nesting by
timestamp containment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The parentSpanId was creating artificial nesting - let the workflow
engine handle span hierarchy naturally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display the branded SENTRY ASCII banner before the intro line for visual
consistency with `sentry --help`. Make the "errors" feature always enabled
in the feature multi-select so users cannot deselect error monitoring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…pt, and source maps hint

Route success-with-exitCode results to formatError so the --force hint
is shown when Sentry is already installed. Fold the "Error Monitoring is
always included" note into the multiselect prompt. Use a more approachable
Source Maps hint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show a non-blocking info note about AI usage with a docs link before
the first network call, and a review reminder before the success outro.
Extract SENTRY_DOCS_URL constant to share between wizard-runner and
clack-utils cancel message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add @anthropic-ai/sdk and openai as devDependencies for the LLM-as-judge
eval framework. Add opencode-lore dependency. Exclude test/init-eval/templates
from biome linting since they are fixture apps, not source code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LLM-as-judge eval tests for the init wizard across all five
platforms (Express, Next.js, Flask, React+Vite, SvelteKit). Each test
runs the wizard end-to-end and asserts on SDK installation, Sentry.init
presence, build success, and documentation accuracy via an LLM judge.

Includes template apps, helper utilities (assertions, doc-fetcher,
judge, platform configs), and feature-docs.json mapping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a separate workflow for running init-eval tests on demand. Supports
running a single platform or all platforms via matrix. Uses the init-eval
GitHub environment for MASTRA_API_URL and OPENAI_API_KEY secrets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store python-fastapi doc URLs as base paths (with trailing slash) like
other platforms, and convert to .md at fetch time. This mirrors the
pattern in cli-init-api and lets us return clean markdown directly
instead of stripping HTML tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Sentry doc URLs for python-flask (getting-started, errors, tracing,
logs, profiling) and add the shared python/profiling page to both flask
and fastapi profiling entries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Sentry doc URLs for all nextjs features: getting-started, errors,
logs, tracing, session replay, metrics, and profiling (browser + node).
Sourcemaps left empty for now.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Sentry doc URLs for sveltekit features and add missing logs,
metrics, and profiling features to the platform entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Sentry doc URLs for react-vite features and add missing logs,
metrics, and profiling features to the platform entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flask eval was using bare `pip install` which fails when pip isn't on
PATH. Use the same venv pattern as fastapi. Also remove accidental
opencode-lore runtime dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Trace

Other

  • (api) Add --data/-d flag and auto-detect JSON body in fields by BYK in #320
  • (formatters) Render all terminal output as markdown by BYK in #297
  • (init) Add init command for guided Sentry project setup by betegon in #283
  • (install) Add Sentry error telemetry to install script by BYK in #334
  • (issue-list) Global limit with fair distribution, compound cursor, and richer progress by BYK in #306
  • (log-list) Add --trace flag to filter logs by trace ID by BYK in #329
  • (logger) Add consola-based structured logging with Sentry integration by BYK in #338
  • (project) Add project create command by betegon in #237
  • (upgrade) Add binary delta patching via TRDIFF10/bsdiff by BYK in #327
  • Support SENTRY_AUTH_TOKEN and SENTRY_TOKEN env vars for headless auth by BYK in #356
  • Improve markdown rendering styles by BYK in #342

Bug Fixes 🐛

Api

  • Use numeric project ID to avoid "not actively selected" error by betegon in #312
  • Use limit param for issues endpoint page size by BYK in #309
  • Auto-correct ':' to '=' in --field values with a warning by BYK in #302

Formatters

  • Expand streaming table to fill terminal width by betegon in #314
  • Fix HTML entities and escaped underscores in table output by betegon in #313

Setup

  • Suppress agent skills and welcome messages on upgrade by BYK in #328
  • Suppress shell completion messages on upgrade by BYK in #326

Upgrade

  • Detect downgrades and skip delta attempt by BYK in #358
  • Check GHCR for nightly version existence instead of GitHub Releases by BYK in #352
  • Replace Bun.mmap with arrayBuffer on all platforms by BYK in #343
  • Replace Bun.mmap with arrayBuffer on macOS to prevent SIGKILL by BYK in #340
  • Use MAP_PRIVATE mmap to prevent macOS SIGKILL during delta upgrade by BYK in #339

Other

  • (ci) Generate JUnit XML to silence codecov-action warnings by BYK in #300
  • (install) Fix nightly digest extraction on macOS by BYK in #331
  • (logger) Inject --verbose and --log-level as proper Stricli flags by BYK in #353
  • (nightly) Push to GHCR from artifacts dir so layer titles are bare filenames by BYK in #301
  • (project create) Auto-correct dot-separated platform to hyphens by BYK in #336
  • (region) Resolve DSN org prefix at resolution layer by BYK in #316
  • (test) Handle 0/-0 in getComparator anti-symmetry property test by BYK in #308
  • (trace-logs) Timestamp_precise is a number, not a string by BYK in #323

Documentation 📚

  • Document SENTRY_URL and self-hosted setup by BYK in #337

Internal Changes 🔧

Api

  • Upgrade @sentry/api to 0.21.0, remove raw HTTP pagination workarounds by BYK in #321
  • Wire listIssuesPaginated through @sentry/api SDK for type safety by BYK in #310

Other

  • (craft) Add sentry-release-registry target by BYK in #325
  • (project create) Migrate human output to markdown rendering system by BYK in #341
  • (telemetry) Add child spans to delta upgrade for bottleneck identification by BYK in #355
  • (upgrade) Use copy-then-mmap for zero JS heap during delta patching by BYK in #344

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

Codecov Results 📊

101 passed | Total: 101 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 95.87%. Project has 3494 uncovered lines.
✅ Project coverage is 82.8%. Comparing base (base) to head (head).

Files with missing lines (8)
File Patch % Lines
local-ops.ts 93.20% ⚠️ 33 Missing
sentry-url-parser.ts 72.73% ⚠️ 30 Missing
app.ts 81.74% ⚠️ 21 Missing
wizard-runner.ts 95.42% ⚠️ 12 Missing
create.ts 95.47% ⚠️ 11 Missing
help.ts 96.81% ⚠️ 3 Missing
utils.ts 88.00% ⚠️ 3 Missing
sentry-urls.ts 98.39% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    81.52%    82.80%    +1.28%
==========================================
  Files          127       135        +8
  Lines        19227     20312     +1085
  Branches         0         0         —
==========================================
+ Hits         15673     16818     +1145
- Misses        3554      3494       -60
- Partials         0         0         —

Generated by Codecov Action

betegon and others added 3 commits February 23, 2026 22:16
Restrict GITHUB_TOKEN to contents:read as flagged by CodeQL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update SvelteKit template with working deps (adapter-node, latest
svelte/vite) and add required src files (app.d.ts, app.html). Use
python3 instead of python for venv creation in Flask/FastAPI platforms.
Add --concurrency 6 to init-eval test runner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add push/pull_request triggers so the eval runs automatically alongside
other CI checks. Keep workflow_dispatch for manual single-platform runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rst-token limitation, unexport FEATURE_INFO

- Add `#` to shell metacharacter blocklist to prevent command truncation
  (e.g. `npm install evil-pkg # @sentry/node`)
- Document Layer 3's first-token-only limitation with explanatory comment
- Remove unnecessary `export` from `FEATURE_INFO` in clack-utils.ts
- Add test for shell comment character blocking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…runtime assertions

- Add WizardOutput, SelectPayload, MultiSelectPayload, ConfirmPayload,
  SuspendPayload types; refactor InteractivePayload as discriminated union
- Remove ~20 unsafe casts across formatters, interactive, and wizard-runner
- Restructure runCommands to validate all commands before executing any
- Add assertWorkflowResult/assertSuspendPayload runtime validation for
  server responses
- Add tests for malformed responses, batch validation, and dry-run paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
betegon and others added 2 commits March 3, 2026 21:00
- safePath() now resolves symlinks and rejects paths that escape the
  project directory via symlink (e.g. link → /etc)
- Add withTimeout() helper to race Mastra API calls against a deadline
- Bump API_TIMEOUT_MS to 120s to match DEFAULT_COMMAND_TIMEOUT_MS
- Delete duplicate isolated test file; consolidate tests in test/lib/
- Add JSDoc to safePath() and withTimeout()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…or patchsets

Restore MASTRA_API_URL to production Cloudflare Worker with env var
override (was hardcoded to localhost:8787). Add upfront safePath()
validation in applyPatchset() so no files are written if any patch
targets an unsafe path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@betegon betegon requested review from BYK and MathurAditya724 March 3, 2026 20:20
…llback (#333)

## Summary

Adds the `create-sentry-project` local operation so the remote workflow
can ask the CLI to create a Sentry project. Resolves the org via local
config / env vars first, falling back to listing orgs from the API
(auto-selects if only one, prompts interactively if multiple).

## Changes

- New `createSentryProject` handler in `local-ops.ts` with extracted
`resolveOrgSlug` helper that handles all org resolution paths (config,
single-org auto-select, multi-org interactive prompt, `--yes` guard)
- `CreateSentryProjectPayload` type added to `types.ts`
- Test suite covering success, single-org fallback, no-orgs, multi-org
`--yes`, interactive select, user cancel, API error, and missing DSN
paths
- Downstream mock setup extracted into `mockDownstreamSuccess` helper to
reduce test duplication

## Test Plan

```bash
bun test test/lib/init/local-ops.create-sentry-project.test.ts  # 8 pass
bun run lint  # clean
```

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
entry.name !== "node_modules"
) {
walk(path.join(dir, entry.name), depth + 1);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directory walk doesn't filter __pycache__ and venv directories

Low Severity

The listDir walk function only skips dot-directories and node_modules when recursing, but doesn't skip __pycache__, venv, .venv, or dist directories. Since this is also used for Python projects (Flask, FastAPI), the pre-computed directory listing sent to the API can be bloated with irrelevant files from virtual environments and bytecode caches, potentially hitting the maxEntries cap before cataloguing meaningful project files.

Fix in Cursor Fix in Web

#354)

## Summary
- Add `getOrgBaseUrl()` helper that builds org-scoped subdomain URLs for
SaaS (e.g. `https://my-org.sentry.io`) while returning the base URL
unchanged for self-hosted instances
- Update all 8 URL builder functions in `sentry-urls.ts` to branch on
SaaS vs self-hosted:
  - **SaaS**: subdomain pattern (`https://my-org.sentry.io/issues/...`)
- **Self-hosted**: path-based pattern
(`https://sentry.company.com/organizations/my-org/issues/...`)
- Add `isSaaS()` private helper that checks the current base URL against
`isSentrySaasUrl()`
- Add self-hosted test coverage verifying all builders produce
path-based URLs with no subdomain prepended

## How this affected our `sentry init` command
- before:
`https://sentry.io/settings/bete-dev/projects/project-created/`
- after: `https://bete-dev.sentry.io/settings/projects/project-created/`

## Test plan
- [x] `bun run typecheck` passes
- [x] `bun run lint` passes
- [x] `bun test test/lib/sentry-urls.property.test.ts` passes (45 tests,
including 10 new self-hosted tests)
- [x] SaaS URLs still use `{org}.sentry.io` subdomain pattern
- [x] Self-hosted URLs use `/organizations/{org}/` or `/settings/{org}/`
path patterns
## Summary

Removes `add-example-trigger` references from the CLI to match the API
repo, where this step was already removed. Cleans up the step label,
confirm handler logic, `purpose` field on `ConfirmPayload`, and 5
related test cases.

## Changes

- Removed `"add-example-trigger"` from `STEP_LABELS` in `clack-utils.ts`
- Removed `addExample` / `isExample` logic from `handleConfirm` in
`interactive.ts`
- Removed optional `purpose` field from `ConfirmPayload` in `types.ts`
- Removed 5 test cases covering example-trigger confirm behavior

## Test plan

- `bun run lint` passes
- `bun test test/lib/init/interactive.test.ts` — remaining confirm tests
pass
- `git grep "addExample\|add-example-trigger\|add-example" -- src/
test/` returns 0 matches

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
betegon and others added 3 commits March 5, 2026 20:05
…hset paths

Previously, applyPatchsetDryRun recorded every patch as applied regardless
of its action, while the real applyPatchset silently skipped unknown actions
via default: break. Both paths now return an explicit error on unrecognized
patch actions so behavior is consistent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The catch block in the suspend/resume loop was showing "Cancelled" for
errors like network timeouts and API failures. Use "Error" to match the
label used in other error paths in the same file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/ci.yml
#	bun.lock
#	src/commands/project/create.ts

spin.start("Scanning project...");
const dirListing = precomputeDirListing(directory);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spinner not stopped if precomputeDirListing throws

Low Severity

The spinner is started with spin.start("Scanning project...") but precomputeDirListing(directory) is called outside the try/catch block that follows. If precomputeDirListing throws (e.g., a permissions error from safePath or readdirSync), the spinner is never stopped, potentially leaving the terminal in a broken state.

Fix in Cursor Fix in Web

The merge conflict resolution inadvertently upgraded @mastra/client-js
to 1.7.2, pulling in @mastra/core@1.9.0 which introduces a quansync
peer dependency that bun 1.3.9 can't resolve with --frozen-lockfile.
Restored lockfile from ba6bd73 and re-resolved to keep @mastra/client-js
pinned at 1.7.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…into try/catch

Track spinner running state via a mutable SpinState object to guard
against calling spin.stop() twice when handleInteractive throws after
the spinner was already stopped. Also moved precomputeDirListing inside
the existing try/catch as a defensive improvement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Skip all API calls (org resolution, team creation, project creation,
DSN fetch) when dryRun is true and return placeholder data instead.
Slug validation is kept before the guard so invalid names are still
caught in dry-run mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

When applyPatchset fails mid-application, the error response now includes
the list of already-applied patches so the server can track partial progress.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

const chosen = abortIfCancelled(selected);
if (hasRequired && !chosen.includes(REQUIRED_FEATURE)) {
chosen.unshift(REQUIRED_FEATURE);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant includes check always evaluates to true

Low Severity

In handleMultiSelect, the optional array is built by filtering out REQUIRED_FEATURE on line 93, so multiselect can never return a value containing it. The guard !chosen.includes(REQUIRED_FEATURE) on line 122 is therefore always true when hasRequired is true, making the includes check dead logic. The condition simplifies to just if (hasRequired).

Additional Locations (1)

Fix in Cursor Fix in Web

const parsed = new URL(base);
parsed.hostname = `${orgSlug}.${parsed.hostname}`;
return parsed.origin;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exported getOrgBaseUrl only used within defining module

Low Severity

getOrgBaseUrl is exported but appears to only be called by sibling URL-builder functions within the same file (sentry-urls.ts). If no external consumer exists, the export widens the public API surface unnecessarily and could invite misuse (e.g., callers building URLs without the correct SaaS/self-hosted path logic that the higher-level builders provide).

Fix in Cursor Fix in Web

{ pattern: "*", label: "glob expansion (*)" },
{ pattern: "?", label: "glob expansion (?)" },
{ pattern: "#", label: "shell comment (#)" },
];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Command validation doesn't block null byte injection

Medium Severity

SHELL_METACHARACTER_PATTERNS does not include the null byte (\0). When commands are passed to spawn with shell: true, a null byte could cause string truncation at the C/shell layer, potentially allowing a crafted command from the remote API to bypass subsequent validation layers. Given commands originate from a remote server, this is worth guarding against.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants